﻿using System;

namespace Halftone
{
    public class QrHelper
    {
        public bool[,] GetAligementPatternlMask(int qrVersion,int blockSize)
        {
            if (qrVersion > 40) throw new ArgumentOutOfRangeException(nameof(qrVersion));
            if (blockSize < 1) throw new ArgumentOutOfRangeException(nameof(blockSize));
            var blocks = (qrVersion - 1) * 4 + 21;
            var piexls = blocks * blockSize;
            var mask = new bool[piexls, piexls];
            if (qrVersion <= 1) return mask;
            var pattens = Statics.AlignmentPatternLocations[qrVersion - 2];
            var l = pattens.Length;
            for (var i = 0; i < l; i++)
            {
                for (var j = 0; j < l; j++)
                {
                    if (i == 0 && j == 0 || i == l - 1 && j == 0 || i == 0 && j == l - 1) continue;
                    for (var k = (pattens[i] - 2) * blockSize; k < (pattens[i] + 3) * blockSize; k++)
                    {
                        for (var m = (pattens[j] - 2) * blockSize; m < (pattens[j] + 3) * blockSize; m++)
                        {
                            mask[k, m] = true;
                        }
                    }
                }
            }
            return mask;
        }

        public bool[,] GetTimingPatternMask(int qrVersion, int blockSize)
        {
            if (qrVersion > 40) throw new ArgumentOutOfRangeException(nameof(qrVersion));
            if (blockSize < 1) throw new ArgumentOutOfRangeException(nameof(blockSize));
            var blocks = (qrVersion - 1) * 4 + 21;
            var piexls = blocks * blockSize;
            var mask = new bool[piexls, piexls];
            for (var i = 6 * blockSize; i < 7 * blockSize; i++)
            {
                for (var j = 8 * blockSize; j < (blocks - 8) * blockSize; j++)
                {
                    mask[i, j] = true;
                    mask[j, i] = true;
                }
            }
            for (var i = 0; i < 8 * blockSize; i++)
            {
                for (var j = 0; j < 8 * blockSize; j++)
                {
                    mask[i, j] = true;
                }
            }
            return mask;
        }

        public bool[,] GetPositionPatternMask(int qrVersion, int blockSize)
        {
            if (qrVersion > 40) throw new ArgumentOutOfRangeException(nameof(qrVersion));
            if (blockSize < 1) throw new ArgumentOutOfRangeException(nameof(blockSize));
            var blocks = (qrVersion - 1) * 4 + 21;
            var piexls = blocks * blockSize;
            var mask = new bool[piexls, piexls];
            for (var i = 0; i < 8 * blockSize; i++)
            {
                for (var j = (blocks - 8) * blockSize; j < blocks * blockSize; j++)
                {
                    mask[i, j] = true;
                    mask[j, i] = true;
                }
                for (int j = 0; j < 8*blockSize; j++)
                {
                    mask[i, j] = true;
                }
            }
            return mask;
        }

        public bool[,] GetCentreDataMask(int qrVersion, int blockSize)
        {
            if (qrVersion > 40) throw new ArgumentOutOfRangeException(nameof(qrVersion));
            if (blockSize < 1) throw new ArgumentOutOfRangeException(nameof(blockSize));
            var blocks = (qrVersion - 1) * 4 + 21;
            var piexls = blocks * blockSize;
            var mask = new bool[piexls, piexls];
            var centreWidth = blockSize/3;
            var centreSkip = (blockSize-centreWidth)/2;
            for (int i = 0; i < piexls; i++)
            {
                var ix = i % blockSize;
                for (int j = 0; j < piexls; j++)
                {
                    var jx = j % blockSize;
                    if (ix >= centreSkip && ix < centreWidth + centreSkip && jx >= centreSkip &&
                        jx < centreWidth + centreSkip)
                    {
                        mask[i, j] = true;
                    }
                }
            }
            return mask;
        }


    }
}
